package utils

import (
	"crypto/md5"
	crand "crypto/rand"
	"encoding/binary"
	"encoding/hex"
	"fmt"
	"github.com/shopspring/decimal"
	"math/rand"
)

func Contains[T int | string](data []T, value T) bool {
	for _, v := range data {
		if v == value {
			return true
		}
	}
	return false
}

func Rands(n int) int64 {
	var seed int64
	binary.Read(crand.Reader, binary.BigEndian, &seed)
	source := rand.NewSource(seed)
	r := rand.New(source)
	number := r.Intn(n)
	return int64(number)
}

func Random(min, max int) int64 {
	var seed int64
	max++
	binary.Read(crand.Reader, binary.BigEndian, &seed)
	source := rand.NewSource(seed)
	r := rand.New(source)
	number := r.Intn(max-min) + min
	return int64(number)
}

func MathInviteCode(num int) string {
	var letters = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
	var bytes = make([]byte, num)
	rand.Read(bytes)
	for k, v := range bytes {
		bytes[k] = letters[v%byte(len(letters))]
	}
	return string(bytes)
}

func GenOrderNumber(prefix string) string {
	datePart := TimeOrDateAsYear(0, "", "YmdHis")
	// 添加固定前缀
	prefixLen := len(prefix)
	randomPart := MathInviteCode(14 - prefixLen)
	return fmt.Sprintf("%s%s%s", prefix, datePart, randomPart)
}

func Md5Password(password string) string {
	data := []byte(password)
	md5New := md5.New()
	md5New.Write(data)
	// hex转字符串
	md5String := hex.EncodeToString(md5New.Sum(nil))
	return md5String
}

// DecimalStringByInt
// num string转int64
// 返回int64
func DecimalStringByInt(num string) int64 {
	fpString, _ := decimal.NewFromString(num)
	return fpString.IntPart()
}

// DecimalStringByFloat
// num string转float64
// 返回float64
func DecimalStringByFloat(num string) float64 {
	fpString, _ := decimal.NewFromString(num)
	return fpString.InexactFloat64()
}

// DecimalFloatByInt
// num float64转int64
// 返回int64
func DecimalFloatByInt(num float64) int64 {
	float := decimal.NewFromFloat(num)
	return float.IntPart()
}

// DecimalIntByFloat
// num int64转float64
// 返回float64
func DecimalIntByFloat(num int64) float64 {
	float := decimal.NewFromInt(num)
	return float.InexactFloat64()
}

// DecimalFloatDiv
// num1 int64转float64
// num2 int64转float64
// 返回num1/num2
func DecimalFloatDiv(num1, num2 float64) float64 {
	numF1 := decimal.NewFromFloat(num1)
	numF2 := decimal.NewFromFloat(num2)
	return numF1.Div(numF2).InexactFloat64()
}

// DecimalIntDiv
// num1 int64转float64
// num2 int64转float64
// 返回num1/num2
func DecimalIntDiv(num1, num2 int64) float64 {
	if num1 <= 0 {
		return 0
	}
	numF1 := decimal.NewFromFloat(DecimalIntByFloat(num1))
	numF2 := decimal.NewFromFloat(DecimalIntByFloat(num2))
	return numF1.Div(numF2).InexactFloat64()
}

// DecimalFloatMul
// num1 float64
// num2 float64
// 返回num1*num2
func DecimalFloatMul(num1 float64, num2 float64) float64 {
	numF1 := decimal.NewFromFloat(num1)
	numF2 := decimal.NewFromFloat(num2)
	mul := numF1.Mul(numF2)
	return mul.InexactFloat64()
}

// DecimalFloatAdd
// num1 float64
// num2 float64
// 返回num1+num2
func DecimalFloatAdd(num1 float64, num2 float64) float64 {
	numF1 := decimal.NewFromFloat(num1)
	numF2 := decimal.NewFromFloat(num2)
	mul := numF1.Add(numF2)
	return mul.InexactFloat64()
}

// DecimalFloatSub
// num1 float64
// num2 float64
// 返回num1-num2
func DecimalFloatSub(num1 float64, num2 float64) float64 {
	numF1 := decimal.NewFromFloat(num1)
	numF2 := decimal.NewFromFloat(num2)
	mul := numF1.Sub(numF2)
	return mul.InexactFloat64()
}

// UpNickname
// nickname string
// 返回 string
func UpNickname(nickname string) string {
	var n string
	for index, runeValue := range nickname {
		if index == 0 {
			n = fmt.Sprintf("%c", runeValue)
			break
		}
	}
	n += "*"

	return n
}
